package br.com.foxinline.modelo;

import br.com.foxinline.enums.CategoriaPessoa;
import br.com.foxinline.enums.EstadoCivil;
import br.com.foxinline.enums.Nacionalidade;
import br.com.foxinline.enums.Sexo;
import br.com.foxinline.enums.TipoPessoa;
import br.com.foxinline.validador.CNPJ;
import br.com.foxinline.validador.CPF;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotBlank;

/**
 *
 * @author laverson
 */
@Entity
public class Pessoa implements Serializable {
    
    @Id
    @SequenceGenerator(name="seq_pessoa", sequenceName="seq_pessoa")
    @GeneratedValue(generator="seq_pessoa", strategy=GenerationType.SEQUENCE)
    private Long id;
    
    @Enumerated(EnumType.STRING)
    private CategoriaPessoa categoriaPessoa;
    
    private boolean ativo = true;
    
    /**
     * Quando é pessoa júridica se refere ao Nome Fantasia
     * Quando é pessoa física se refere ao nome da pessoa.
     */
    private String nome;
    
    /**
     * Quando é pessoa júridica se refere ao slugNome Fantasia
     * Quando é pessoa física se refere ao slugnome da pessoa.
     */
    private String slugNome;

    @Size(max=255, message="Razão Social deve ter no máximo 255 caracteres.")
    private String razaoSocial;

    @Column(length=60)
    @Size(max=60, message="Responsável deve ter no máximo 60 caracteres.")
    private String responsavel;
        
    @Past(message="Data de Cadastro deve ser igual ou anterior a atual.")
    @Temporal(TemporalType.DATE)
    private Date dataCadastro;
    
    @Past(message="Data de Nascimento deve ser igual ou anterior a atual.")
    @Temporal(TemporalType.DATE)
    private Date dataNascimento;    

    @Enumerated(EnumType.STRING)
    private Nacionalidade nacionalidade;

    @Enumerated(EnumType.STRING)    
    private TipoPessoa tipoPessoa;    
    
    @Column(length=20)
    private String rg;

    @Column(length=20)
    private String rne;
    
    private String outros;

    @Column(length=20)
    private String documentoComplemento;
    
    @Column(length=11)
    @CPF
    private String cpf;
    
    @Column(length=14)
    @CNPJ
    private String cnpj;

    private String OAB;

    @ManyToOne
    private Estado UFOAB;
    
    private String orgaoEmissor;

    @Enumerated(EnumType.STRING)
    private EstadoCivil estadoCivil;
    
    @Column(length=60)
    @Size(max=60, message="Profissão deve ter no máximo 60 caracteres.")
    private String profissao;
        
    @Enumerated(EnumType.STRING)
    private Sexo sexo;
    
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    private List<Telefone> telefones;

    @Column(length=60)
    @Size(max=60, message="Email deve ter no máximo 60 caracteres.")
    private String email;    

    @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private Endereco endereco;
    
    @ManyToOne
    private Pais paisNascimento;
    
    @ManyToOne
    private Estado estadoNascimento;

    @ManyToOne
    private Pais paisResidencia;
    
    @ManyToOne
    private Estado estadoResidencia;

    @ManyToOne
    private Cidade cidadeResidencia;
    
    private String nomeMae;
    
    private String nomePai;   
    
    /**
     * Lista de contas bancárias
     */
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    private List<ContaBancaria> contasBancarias;

    public Pessoa() {}

    public Pessoa(Long id, CategoriaPessoa categoriaPessoa, String nome, String slugNome, String razaoSocial, String responsavel, Date dataCadastro, Date dataNascimento, Nacionalidade nacionalidade, TipoPessoa tipoPessoa, String rg, String rne, String outros, String documentoComplemento, String cpf, String cnpj, String OAB, Estado UFOAB, String orgaoEmissor, EstadoCivil estadoCivil, String profissao, Sexo sexo, List<Telefone> telefones, String email, Endereco endereco, Pais paisNascimento, Estado estadoNascimento, Pais paisResidencia, Estado estadoResidencia, Cidade cidadeResidencia, String nomeMae, String nomePai, List<ContaBancaria> contasBancarias) {
        this.id = id;
        this.categoriaPessoa = categoriaPessoa;
        this.nome = nome;
        this.slugNome = slugNome;
        this.razaoSocial = razaoSocial;
        this.responsavel = responsavel;
        this.dataCadastro = dataCadastro;
        this.dataNascimento = dataNascimento;
        this.nacionalidade = nacionalidade;
        this.tipoPessoa = tipoPessoa;
        this.rg = rg;
        this.rne = rne;
        this.outros = outros;
        this.documentoComplemento = documentoComplemento;
        this.cpf = cpf;
        this.cnpj = cnpj;
        this.OAB = OAB;
        this.UFOAB = UFOAB;
        this.orgaoEmissor = orgaoEmissor;
        this.estadoCivil = estadoCivil;
        this.profissao = profissao;
        this.sexo = sexo;
        this.telefones = telefones;
        this.email = email;
        this.endereco = endereco;
        this.paisNascimento = paisNascimento;
        this.estadoNascimento = estadoNascimento;
        this.paisResidencia = paisResidencia;
        this.estadoResidencia = estadoResidencia;
        this.cidadeResidencia = cidadeResidencia;
        this.nomeMae = nomeMae;
        this.nomePai = nomePai;
        this.contasBancarias = contasBancarias;
    }

    public String getOAB() {
        return OAB;
    }

    public void setOAB(String OAB) {
        this.OAB = OAB;
    }

    public Estado getUFOAB() {
        return UFOAB;
    }

    public void setUFOAB(Estado UFOAB) {
        this.UFOAB = UFOAB;
    }

    public boolean isAtivo() {
        return ativo;
    }

    public void setAtivo(boolean ativo) {
        this.ativo = ativo;
    }

    public CategoriaPessoa getCategoriaPessoa() {
        return categoriaPessoa;
    }

    public void setCategoriaPessoa(CategoriaPessoa categoriaPessoa) {
        this.categoriaPessoa = categoriaPessoa;
    }

    public Cidade getCidadeResidencia() {
        return cidadeResidencia;
    }

    public void setCidadeResidencia(Cidade cidadeResidencia) {
        this.cidadeResidencia = cidadeResidencia;
    }

    public String getCnpj() {
        return cnpj;
    }

    public void setCnpj(String cnpj) {
        this.cnpj = cnpj;
    }

    public List<ContaBancaria> getContasBancarias() {
        return contasBancarias;
    }

    public void setContasBancarias(List<ContaBancaria> contasBancarias) {
        this.contasBancarias = contasBancarias;
    }

    public String getCpf() {
        return cpf;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    public Date getDataCadastro() {
        return dataCadastro;
    }

    public void setDataCadastro(Date dataCadastro) {
        this.dataCadastro = dataCadastro;
    }

    public Date getDataNascimento() {
        return dataNascimento;
    }

    public void setDataNascimento(Date dataNascimento) {
        this.dataNascimento = dataNascimento;
    }

    public String getDocumentoComplemento() {
        return documentoComplemento;
    }

    public void setDocumentoComplemento(String documentoComplemento) {
        this.documentoComplemento = documentoComplemento;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Endereco getEndereco() {
        return endereco;
    }

    public void setEndereco(Endereco endereco) {
        this.endereco = endereco;
    }

    public EstadoCivil getEstadoCivil() {
        return estadoCivil;
    }

    public void setEstadoCivil(EstadoCivil estadoCivil) {
        this.estadoCivil = estadoCivil;
    }

    public Estado getEstadoNascimento() {
        return estadoNascimento;
    }

    public void setEstadoNascimento(Estado estadoNascimento) {
        this.estadoNascimento = estadoNascimento;
    }

    public Estado getEstadoResidencia() {
        return estadoResidencia;
    }

    public void setEstadoResidencia(Estado estadoResidencia) {
        this.estadoResidencia = estadoResidencia;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getNomeMae() {
        return nomeMae;
    }

    public void setNomeMae(String nomeMae) {
        this.nomeMae = nomeMae;
    }

    public String getNomePai() {
        return nomePai;
    }

    public void setNomePai(String nomePai) {
        this.nomePai = nomePai;
    }

    public String getOrgaoEmissor() {
        return orgaoEmissor;
    }

    public void setOrgaoEmissor(String orgaoEmissor) {
        this.orgaoEmissor = orgaoEmissor;
    }

    public String getOutros() {
        return outros;
    }

    public void setOutros(String outros) {
        this.outros = outros;
    }

    public Pais getPaisNascimento() {
        return paisNascimento;
    }

    public void setPaisNascimento(Pais paisNascimento) {
        this.paisNascimento = paisNascimento;
    }

    public Pais getPaisResidencia() {
        return paisResidencia;
    }

    public void setPaisResidencia(Pais paisResidencia) {
        this.paisResidencia = paisResidencia;
    }

    public String getProfissao() {
        return profissao;
    }

    public void setProfissao(String profissao) {
        this.profissao = profissao;
    }

    public String getRazaoSocial() {
        return razaoSocial;
    }

    public void setRazaoSocial(String razaoSocial) {
        this.razaoSocial = razaoSocial;
    }

    public String getResponsavel() {
        return responsavel;
    }

    public void setResponsavel(String responsavel) {
        this.responsavel = responsavel;
    }

    public String getRg() {
        return rg;
    }

    public void setRg(String rg) {
        this.rg = rg;
    }

    public String getRne() {
        return rne;
    }

    public void setRne(String rne) {
        this.rne = rne;
    }

    public Sexo getSexo() {
        return sexo;
    }

    public void setSexo(Sexo sexo) {
        this.sexo = sexo;
    }

    public String getSlugNome() {
        return slugNome;
    }

    public void setSlugNome(String slugNome) {
        this.slugNome = slugNome;
    }

    public List<Telefone> getTelefones() {
        return telefones;
    }

    public void setTelefones(List<Telefone> telefones) {
        this.telefones = telefones;
    }

    public TipoPessoa getTipoPessoa() {
        return tipoPessoa;
    }

    public void setTipoPessoa(TipoPessoa tipoPessoa) {
        this.tipoPessoa = tipoPessoa;
    }

    public Nacionalidade getNacionalidade() {
        return nacionalidade;
    }

    public void setNacionalidade(Nacionalidade nacionalidade) {
        this.nacionalidade = nacionalidade;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Pessoa other = (Pessoa) obj;
        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
            return false;
        }
        if (this.categoriaPessoa != other.categoriaPessoa) {
            return false;
        }
        if (this.ativo != other.ativo) {
            return false;
        }
        if ((this.nome == null) ? (other.nome != null) : !this.nome.equals(other.nome)) {
            return false;
        }
        if ((this.slugNome == null) ? (other.slugNome != null) : !this.slugNome.equals(other.slugNome)) {
            return false;
        }
        if ((this.razaoSocial == null) ? (other.razaoSocial != null) : !this.razaoSocial.equals(other.razaoSocial)) {
            return false;
        }
        if ((this.responsavel == null) ? (other.responsavel != null) : !this.responsavel.equals(other.responsavel)) {
            return false;
        }
        if (this.dataCadastro != other.dataCadastro && (this.dataCadastro == null || !this.dataCadastro.equals(other.dataCadastro))) {
            return false;
        }
        if (this.dataNascimento != other.dataNascimento && (this.dataNascimento == null || !this.dataNascimento.equals(other.dataNascimento))) {
            return false;
        }
        if (this.nacionalidade != other.nacionalidade) {
            return false;
        }
        if (this.tipoPessoa != other.tipoPessoa) {
            return false;
        }
        if ((this.rg == null) ? (other.rg != null) : !this.rg.equals(other.rg)) {
            return false;
        }
        if ((this.rne == null) ? (other.rne != null) : !this.rne.equals(other.rne)) {
            return false;
        }
        if ((this.outros == null) ? (other.outros != null) : !this.outros.equals(other.outros)) {
            return false;
        }
        if ((this.documentoComplemento == null) ? (other.documentoComplemento != null) : !this.documentoComplemento.equals(other.documentoComplemento)) {
            return false;
        }
        if ((this.cpf == null) ? (other.cpf != null) : !this.cpf.equals(other.cpf)) {
            return false;
        }
        if ((this.cnpj == null) ? (other.cnpj != null) : !this.cnpj.equals(other.cnpj)) {
            return false;
        }
        if ((this.OAB == null) ? (other.OAB != null) : !this.OAB.equals(other.OAB)) {
            return false;
        }
        if (this.UFOAB != other.UFOAB && (this.UFOAB == null || !this.UFOAB.equals(other.UFOAB))) {
            return false;
        }
        if ((this.orgaoEmissor == null) ? (other.orgaoEmissor != null) : !this.orgaoEmissor.equals(other.orgaoEmissor)) {
            return false;
        }
        if (this.estadoCivil != other.estadoCivil) {
            return false;
        }
        if ((this.profissao == null) ? (other.profissao != null) : !this.profissao.equals(other.profissao)) {
            return false;
        }
        if (this.sexo != other.sexo) {
            return false;
        }
        if (this.telefones != other.telefones && (this.telefones == null || !this.telefones.equals(other.telefones))) {
            return false;
        }
        if ((this.email == null) ? (other.email != null) : !this.email.equals(other.email)) {
            return false;
        }
        if (this.endereco != other.endereco && (this.endereco == null || !this.endereco.equals(other.endereco))) {
            return false;
        }
        if (this.paisNascimento != other.paisNascimento && (this.paisNascimento == null || !this.paisNascimento.equals(other.paisNascimento))) {
            return false;
        }
        if (this.estadoNascimento != other.estadoNascimento && (this.estadoNascimento == null || !this.estadoNascimento.equals(other.estadoNascimento))) {
            return false;
        }
        if (this.paisResidencia != other.paisResidencia && (this.paisResidencia == null || !this.paisResidencia.equals(other.paisResidencia))) {
            return false;
        }
        if (this.estadoResidencia != other.estadoResidencia && (this.estadoResidencia == null || !this.estadoResidencia.equals(other.estadoResidencia))) {
            return false;
        }
        if (this.cidadeResidencia != other.cidadeResidencia && (this.cidadeResidencia == null || !this.cidadeResidencia.equals(other.cidadeResidencia))) {
            return false;
        }
        if ((this.nomeMae == null) ? (other.nomeMae != null) : !this.nomeMae.equals(other.nomeMae)) {
            return false;
        }
        if ((this.nomePai == null) ? (other.nomePai != null) : !this.nomePai.equals(other.nomePai)) {
            return false;
        }
        if (this.contasBancarias != other.contasBancarias && (this.contasBancarias == null || !this.contasBancarias.equals(other.contasBancarias))) {
            return false;
        }
        return true;
    }    
    
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 37 * hash + (this.id != null ? this.id.hashCode() : 0);
        hash = 37 * hash + (this.categoriaPessoa != null ? this.categoriaPessoa.hashCode() : 0);
        hash = 37 * hash + (this.ativo ? 1 : 0);
        hash = 37 * hash + (this.nome != null ? this.nome.hashCode() : 0);
        hash = 37 * hash + (this.slugNome != null ? this.slugNome.hashCode() : 0);
        hash = 37 * hash + (this.razaoSocial != null ? this.razaoSocial.hashCode() : 0);
        hash = 37 * hash + (this.responsavel != null ? this.responsavel.hashCode() : 0);
        hash = 37 * hash + (this.dataCadastro != null ? this.dataCadastro.hashCode() : 0);
        hash = 37 * hash + (this.dataNascimento != null ? this.dataNascimento.hashCode() : 0);
        hash = 37 * hash + (this.nacionalidade != null ? this.nacionalidade.hashCode() : 0);
        hash = 37 * hash + (this.tipoPessoa != null ? this.tipoPessoa.hashCode() : 0);
        hash = 37 * hash + (this.rg != null ? this.rg.hashCode() : 0);
        hash = 37 * hash + (this.rne != null ? this.rne.hashCode() : 0);
        hash = 37 * hash + (this.outros != null ? this.outros.hashCode() : 0);
        hash = 37 * hash + (this.documentoComplemento != null ? this.documentoComplemento.hashCode() : 0);
        hash = 37 * hash + (this.cpf != null ? this.cpf.hashCode() : 0);
        hash = 37 * hash + (this.cnpj != null ? this.cnpj.hashCode() : 0);
        hash = 37 * hash + (this.OAB != null ? this.OAB.hashCode() : 0);
        hash = 37 * hash + (this.UFOAB != null ? this.UFOAB.hashCode() : 0);
        hash = 37 * hash + (this.orgaoEmissor != null ? this.orgaoEmissor.hashCode() : 0);
        hash = 37 * hash + (this.estadoCivil != null ? this.estadoCivil.hashCode() : 0);
        hash = 37 * hash + (this.profissao != null ? this.profissao.hashCode() : 0);
        hash = 37 * hash + (this.sexo != null ? this.sexo.hashCode() : 0);
        hash = 37 * hash + (this.telefones != null ? this.telefones.hashCode() : 0);
        hash = 37 * hash + (this.email != null ? this.email.hashCode() : 0);
        hash = 37 * hash + (this.endereco != null ? this.endereco.hashCode() : 0);
        hash = 37 * hash + (this.paisNascimento != null ? this.paisNascimento.hashCode() : 0);
        hash = 37 * hash + (this.estadoNascimento != null ? this.estadoNascimento.hashCode() : 0);
        hash = 37 * hash + (this.paisResidencia != null ? this.paisResidencia.hashCode() : 0);
        hash = 37 * hash + (this.estadoResidencia != null ? this.estadoResidencia.hashCode() : 0);
        hash = 37 * hash + (this.cidadeResidencia != null ? this.cidadeResidencia.hashCode() : 0);
        hash = 37 * hash + (this.nomeMae != null ? this.nomeMae.hashCode() : 0);
        hash = 37 * hash + (this.nomePai != null ? this.nomePai.hashCode() : 0);
        hash = 37 * hash + (this.contasBancarias != null ? this.contasBancarias.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return "Pessoa{" + "id=" + id + ", categoriaPessoa=" + categoriaPessoa + ", ativo=" + ativo + ", nome=" + nome + ", slugNome=" + slugNome + ", razaoSocial=" + razaoSocial + ", responsavel=" + responsavel + ", dataCadastro=" + dataCadastro + ", dataNascimento=" + dataNascimento + ", nacionalidade=" + nacionalidade + ", tipoPessoa=" + tipoPessoa + ", rg=" + rg + ", rne=" + rne + ", outros=" + outros + ", documentoComplemento=" + documentoComplemento + ", cpf=" + cpf + ", cnpj=" + cnpj + ", OAB=" + OAB + ", UFOAB=" + UFOAB + ", orgaoEmissor=" + orgaoEmissor + ", estadoCivil=" + estadoCivil + ", profissao=" + profissao + ", sexo=" + sexo + ", telefones=" + telefones + ", email=" + email + ", endereco=" + endereco + ", paisNascimento=" + paisNascimento + ", estadoNascimento=" + estadoNascimento + ", paisResidencia=" + paisResidencia + ", estadoResidencia=" + estadoResidencia + ", cidadeResidencia=" + cidadeResidencia + ", nomeMae=" + nomeMae + ", nomePai=" + nomePai + ", contasBancarias=" + contasBancarias + '}';
    }

}
